/*
 * bsp_nfc_reader.c
 *
 *  Created on: 2023年8月25日
 *      Author: fjx
 */
#include "bsp_nfc.h"
#include "bsp_nfc_fm17622_reg.h"
#include "bsp_nfc_reader.h"
#include <string.h>
#include "app_gpio_i2c_fm17622.h"


#ifdef FM17622_DRIVER

static const unsigned char RF_CMD_REQA = 0x26;
static const unsigned char RF_CMD_WUPA  = 0x52;
static const unsigned char RF_CMD_ANTICOL = 0x93;
static const unsigned char RF_CMD_SELECT = 0x93;

struct picc_a_struct PICC_A;
struct picc_b_struct PICC_B;


#define BIT0               0x01
#define BIT1               0x02
#define BIT2               0x04
#define BIT3               0x08
#define BIT4               0x10
#define BIT5               0x20
#define BIT6               0x40
#define BIT7               0x80


/*
 *@brief readerA 初始化
 */
void fm17622_init_readerA (void)
{
  fm17622_set_reg(JREG_MODWIDTH,MODWIDTH_106); //MODWIDTH = 106kbps
  fm17622_modify_reg(JREG_TXAUTO,BIT6,SET);//Force 100ASK = 1
  fm17622_set_reg(JREG_GSN,(GSNON_A<<4));//Config GSN; Config ModGSN
  fm17622_set_reg(JREG_CWGSP,GSP_A);//Config GSP
  fm17622_set_reg(JREG_CONTROL,BIT4);//Initiator = 1
  fm17622_set_reg(JREG_RFCFG,RXGAIN_A<<4);//Config RxGain
  fm17622_set_reg(JREG_RXTRESHOLD,(MINLEVEL_A<<4) | COLLLEVEL_A);//Config MinLevel; Config CollLevel

}

/*
 * @brief readerB 初始化
 *
 */
void fm17622_init_readerB (void)
{
  fm17622_modify_reg(JREG_STATUS2,BIT3,RESET);

  fm17622_set_reg(JREG_MODWIDTH,MODWIDTH_106);//MODWIDTH = 106kbps
  fm17622_set_reg(JREG_TXAUTO,0);//Force 100ASK = 0
  fm17622_set_reg(JREG_GSN,(GSNON_B<<4)|MODGSNON_B);//Config GSN; Config ModGSN
  fm17622_set_reg(JREG_CWGSP,GSP_B);//Config GSP
  fm17622_set_reg(JREG_MODGSP,MODGSP_B);//Config ModGSP
  fm17622_set_reg(JREG_CONTROL,BIT4);//Initiator = 1
  fm17622_set_reg(JREG_RFCFG,RXGAIN_B<<4);//Config RxGain
  fm17622_set_reg(JREG_RXTRESHOLD,MINLEVEL_B<<4);//Config MinLevel;
}


/*
*@brief ReaderA_Halt
*
* @ return ：FM17622_SUCCESS, FM17622_COMM_ERR
*/
uint8_t ReaderA_Halt(void)
{
  unsigned char reg_data;
  fm17622_set_reg(JREG_TXMODE,0x80);//Enable TxCRC
  fm17622_set_reg(JREG_RXMODE,0x80);//Enable RxCRC
  fm17622_set_reg(JREG_COMMAND,CMD_IDLE);//command = Idel
  fm17622_set_reg(JREG_FIFOLEVEL,JBIT_FLUSHFIFO);//Clear FIFO
  fm17622_set_reg(JREG_FIFODATA,0x50);
  fm17622_set_reg(JREG_FIFODATA,0x00);
  fm17622_set_reg(JREG_COMMAND,CMD_TRANSMIT);//command = Transceive
  fm17622_set_reg(JREG_BITFRAMING,0x80);//Start Send
  mDelay(2);//Wait 2ms TODO: 需要操作delay
  fm17622_get_reg(JREG_FIFOLEVEL,&reg_data);
  if(reg_data == 0)
  {
      return FM17622_SUCCESS;
  }
  return FM17622_COMM_ERR;
}
/*
*@brief ReaderA_Wakeup
*
* return FM17622_SUCCESS, FM17622_COMM_ERR
*/
uint8_t ReaderA_Wakeup(void)
{
  uint8_t reg_data;
  fm17622_set_reg(JREG_TXMODE,0);//Disable TxCRC
  fm17622_set_reg(JREG_RXMODE,0);//Disable RxCRC
  fm17622_set_reg(JREG_COMMAND,CMD_IDLE);//command = Idel
  fm17622_set_reg(JREG_FIFOLEVEL,JBIT_FLUSHFIFO);//Clear FIFO
  fm17622_set_reg(JREG_FIFODATA,RF_CMD_WUPA);
  fm17622_set_reg(JREG_COMMAND,CMD_TRANSCEIVE);//command = Transceive
  fm17622_set_reg(JREG_BITFRAMING,0x87);//Start Send
  mDelay(1);//Wait 1ms TODO:需要操作delay
  fm17622_get_reg(JREG_FIFOLEVEL,&reg_data);
  if(reg_data == 2)
  {
      fm17622_get_reg(JREG_FIFODATA,PICC_A.ATQA);
      fm17622_get_reg(JREG_FIFODATA,PICC_A.ATQA+1);
      return FM17622_SUCCESS;
  }
  return FM17622_COMM_ERR;
}
/*
*@brief：ReaderA_Request
*@return FM17622_SUCCESS, FM17622_COMM_ERR
*/
uint8_t ReaderA_Request(void)
{
  uint8_t reg_data;
  fm17622_set_reg(JREG_TXMODE,0);//Disable TxCRC
  fm17622_set_reg(JREG_RXMODE,0);//Disable RxCRC
  fm17622_set_reg(JREG_COMMAND,CMD_IDLE);//command = Idel
  fm17622_set_reg(JREG_FIFOLEVEL,JBIT_FLUSHFIFO);//Clear FIFO
  fm17622_set_reg(JREG_FIFODATA,RF_CMD_REQA);
  fm17622_set_reg(JREG_COMMAND,CMD_TRANSCEIVE);//command = Transceive
  fm17622_set_reg(JREG_BITFRAMING,0x87);//Start Send
  mDelay(2);//Wait 2ms  TODO:需要操作延时
  fm17622_get_reg(JREG_FIFOLEVEL,&reg_data);
  if(reg_data == 2)
  {
      fm17622_get_reg(JREG_FIFODATA,PICC_A.ATQA);
      fm17622_get_reg(JREG_FIFODATA,PICC_A.ATQA+1);
      return FM17622_SUCCESS;
  }
  return FM17622_COMM_ERR;
}

/*
*@brief ReaderA_AntiColl
*@return FM17622_SUCCESS, FM17622_COMM_ERR
*/
uint8_t ReaderA_AntiColl(void)
{
  uint8_t reg_data;
  fm17622_set_reg(JREG_TXMODE,0);//Disable TxCRC
  fm17622_set_reg(JREG_RXMODE,0);//Disable RxCRC
  fm17622_set_reg(JREG_COMMAND,CMD_IDLE);//command = Idel
  fm17622_set_reg(JREG_FIFOLEVEL,JBIT_FLUSHFIFO);//Clear FIFO
  fm17622_set_reg(JREG_FIFODATA,RF_CMD_ANTICOL);
  fm17622_set_reg(JREG_FIFODATA,0x20);
  fm17622_set_reg(JREG_COMMAND,CMD_TRANSCEIVE);//command = Transceive
  fm17622_set_reg(JREG_BITFRAMING,0x80);//Start Send
  mDelay(2);//Wait 2ms  TODO:需要操作延时
  fm17622_get_reg(JREG_FIFOLEVEL,&reg_data);
  if(reg_data == 5)
  {
      fm17622_get_reg(JREG_FIFODATA,PICC_A.UID);
      fm17622_get_reg(JREG_FIFODATA,PICC_A.UID+1);
      fm17622_get_reg(JREG_FIFODATA,PICC_A.UID+2);
      fm17622_get_reg(JREG_FIFODATA,PICC_A.UID+3);
      fm17622_get_reg(JREG_FIFODATA,&PICC_A.BCC);
      if( (PICC_A.UID[0] ^ PICC_A.UID[1] ^ PICC_A.UID[2] ^ PICC_A.UID[3]) == PICC_A.BCC)
        return FM17622_SUCCESS;
  }
  return FM17622_COMM_ERR;
}

/*
*@brief ReaderA_Select
*@return FM17622_SUCCESS, FM17622_COMM_ERR
*/
uint8_t ReaderA_Select(void)
{
  uint8_t reg_data;
  fm17622_set_reg(JREG_TXMODE,0x80);//Enable TxCRC
  fm17622_set_reg(JREG_RXMODE,0x80);//Enable RxCRC
  fm17622_set_reg(JREG_COMMAND,CMD_IDLE);//command = Idel
  fm17622_set_reg(JREG_FIFOLEVEL,JBIT_FLUSHFIFO);//Clear FIFO
  fm17622_set_reg(JREG_FIFODATA,0x93);
  fm17622_set_reg(JREG_FIFODATA,0x70);
  fm17622_set_reg(JREG_FIFODATA,PICC_A.UID[0]);
  fm17622_set_reg(JREG_FIFODATA,PICC_A.UID[1]);
  fm17622_set_reg(JREG_FIFODATA,PICC_A.UID[2]);
  fm17622_set_reg(JREG_FIFODATA,PICC_A.UID[3]);
  fm17622_set_reg(JREG_FIFODATA,PICC_A.BCC);
  fm17622_set_reg(JREG_COMMAND,CMD_TRANSCEIVE);//command = Transceive
  fm17622_set_reg(JREG_BITFRAMING,0x80);//Start Send
  mDelay(2);//Wait 2ms TODO:需要操作延时
  fm17622_get_reg(JREG_FIFOLEVEL,&reg_data);
  if(reg_data == 1)
  {
      fm17622_get_reg(JREG_FIFODATA,&PICC_A.SAK);
      return FM17622_SUCCESS;
  }
  return FM17622_COMM_ERR;
}

/*
*@brief  ReaderA_CardActivate
*@return FM17622_SUCCESS, FM17622_COMM_ERR
*/
uint8_t ReaderA_CardActivate(void)
{
  uint8_t result;

  result = ReaderA_Request();//
  if (result != FM17622_SUCCESS){
      return FM17622_COMM_ERR;
  }

  result = ReaderA_AntiColl();//
  if (result != FM17622_SUCCESS)
      return FM17622_COMM_ERR;

  result = ReaderA_Select();//
  if (result != FM17622_SUCCESS)
      return FM17622_COMM_ERR;

  return result;
}
/*
*@brief  ReaderB_Wakeup
*@return FM17622_SUCCESS, FM17622_COMM_ERR
*/
uint8_t ReaderB_Wakeup(void)
{
  uint8_t reg_data,i;
  fm17622_set_reg(JREG_TXMODE,0x83);//Enable TxCRC
  fm17622_set_reg(JREG_RXMODE,0x83);//Enable RxCRC
  fm17622_set_reg(JREG_COMMAND,CMD_IDLE);//command = Idel
  fm17622_set_reg(JREG_FIFOLEVEL,JBIT_FLUSHFIFO);//Clear FIFO
  fm17622_set_reg(JREG_FIFODATA,0x05);
  fm17622_set_reg(JREG_FIFODATA,0x00);
  fm17622_set_reg(JREG_FIFODATA,0x08);

  fm17622_set_reg(JREG_COMMAND,CMD_TRANSCEIVE);//command = Transceive
  fm17622_set_reg(JREG_BITFRAMING,0x80);//Start Send
  mDelay(10);//Wait 10ms  TODO:需要操作延时
  fm17622_get_reg(JREG_FIFOLEVEL,&reg_data);
  if(reg_data == 12){
      for(i = 0;i < 12;i++)
          fm17622_get_reg(JREG_FIFODATA,&PICC_B.ATQB[i]);
      memcpy(PICC_B.PUPI,PICC_B.ATQB + 1,4);  //TODO:此处SDK是否需要进行for
      memcpy(PICC_B.APPLICATION_DATA,PICC_B.ATQB + 6,4);
      memcpy(PICC_B.PROTOCOL_INF,PICC_B.ATQB + 10,3);
      return FM17622_SUCCESS;
  }
  return FM17622_COMM_ERR;
}
/*
*@brief  ReaderB_Request
*@return FM17622_SUCCESS, FM17622_COMM_ERR
*/
uint8_t ReaderB_Request(void)
{
  uint8_t reg_data,i;
  fm17622_set_reg(JREG_TXMODE,0x83);//Enable TxCRC
  fm17622_set_reg(JREG_RXMODE,0x83);//Enable RxCRC
  fm17622_set_reg(JREG_COMMAND,CMD_IDLE);//command = Idel
  fm17622_set_reg(JREG_FIFOLEVEL,JBIT_FLUSHFIFO);//Clear FIFO
  fm17622_set_reg(JREG_FIFODATA,0x05);
  fm17622_set_reg(JREG_FIFODATA,0x00);
  fm17622_set_reg(JREG_FIFODATA,0x00);

  fm17622_set_reg(JREG_COMMAND,CMD_TRANSCEIVE);//command = Transceive
  fm17622_set_reg(JREG_BITFRAMING,0x80);//Start Send
  mDelay(10);//Wait 10ms  TODO:需要操作延时
  fm17622_get_reg(JREG_FIFOLEVEL,&reg_data);
  if(reg_data == 12)
  {
      for(i = 0;i < 12;i++)
        fm17622_get_reg(JREG_FIFODATA,&PICC_B.ATQB[i]);
      memcpy(PICC_B.PUPI,PICC_B.ATQB + 1,4);
      memcpy(PICC_B.APPLICATION_DATA,PICC_B.ATQB + 6,4);
      memcpy(PICC_B.PROTOCOL_INF,PICC_B.ATQB + 10,3);
      return FM17622_SUCCESS;
  }
  return FM17622_COMM_ERR;
}
/*
*@brief  ReaderB_Attrib
*@return FM17622_SUCCESS, FM17622_COMM_ERR
*/
uint8_t ReaderB_Attrib(void)
{
  uint8_t reg_data;
  fm17622_set_reg(JREG_TXMODE,0x83);//Enable TxCRC
  fm17622_set_reg(JREG_RXMODE,0x83);//Enable RxCRC
  fm17622_set_reg(JREG_COMMAND,CMD_IDLE);//command = Idel
  fm17622_set_reg(JREG_FIFOLEVEL,JBIT_FLUSHFIFO);//Clear FIFO
  fm17622_set_reg(JREG_FIFODATA,0x1D);
  fm17622_set_reg(JREG_FIFODATA,PICC_B.PUPI[0]);
  fm17622_set_reg(JREG_FIFODATA,PICC_B.PUPI[1]);
  fm17622_set_reg(JREG_FIFODATA,PICC_B.PUPI[2]);
  fm17622_set_reg(JREG_FIFODATA,PICC_B.PUPI[3]);
  fm17622_set_reg(JREG_FIFODATA,0x00);
  fm17622_set_reg(JREG_FIFODATA,0x08);
  fm17622_set_reg(JREG_FIFODATA,0x01);
  fm17622_set_reg(JREG_FIFODATA,0x01);
  fm17622_set_reg(JREG_COMMAND,CMD_TRANSCEIVE);//command = Transceive
  fm17622_set_reg(JREG_BITFRAMING,0x80);//Start Send
  mDelay(10);//Wait 10ms  TODO:需要操作延时
  fm17622_get_reg(JREG_FIFOLEVEL,&reg_data);
  if(reg_data == 1)
  {
      fm17622_get_reg(JREG_FIFODATA,PICC_B.ATTRIB);
      return FM17622_SUCCESS;
  }
  return FM17622_COMM_ERR;
}
/*
*@brief  ReaderB_GetUID
*@return FM17622_SUCCESS, FM17622_COMM_ERR
*/
uint8_t ReaderB_GetUID(void)
{
  uint8_t reg_data,i;
  fm17622_set_reg(JREG_TXMODE,0x83);//Enable TxCRC
  fm17622_set_reg(JREG_RXMODE,0x83);//Enable RxCRC
  fm17622_set_reg(JREG_COMMAND,CMD_IDLE);//command = Idel
  fm17622_set_reg(JREG_FIFOLEVEL,JBIT_FLUSHFIFO);//Clear FIFO
  fm17622_set_reg(JREG_FIFODATA,0x00);
  fm17622_set_reg(JREG_FIFODATA,0x36);
  fm17622_set_reg(JREG_FIFODATA,0x00);
  fm17622_set_reg(JREG_FIFODATA,0x00);
  fm17622_set_reg(JREG_FIFODATA,0x08);
  fm17622_set_reg(JREG_COMMAND,CMD_TRANSCEIVE);//command = Transceive
  fm17622_set_reg(JREG_BITFRAMING,0x80);//Start Send
  mDelay(10);//Wait 10ms  //TODO:需要操作延时
  fm17622_get_reg(JREG_FIFOLEVEL,&reg_data);
  if(reg_data == 10)
  {
    for(i=0;i<8;i++)
      fm17622_get_reg(JREG_FIFODATA,&PICC_B.UID[i]);
    return FM17622_SUCCESS;
  }
  return FM17622_COMM_ERR;
}
/*
*@brief  FM17622_Polling
*@return FM17622_SUCCESS, FM17622_COMM_ERR
*/
uint8_t FM17622_Polling(unsigned char *polling_card)
{
  uint8_t result;

  *polling_card = 0;
  fm17622_soft_reset();
  fm17622_init_readerA();
  fm17622_setcw(TX1_TX2_CW_ENABLE);
  result = ReaderA_Wakeup();//
  if (result == FM17622_SUCCESS){
      *polling_card |= BIT0;
  }
  fm17622_init_readerB();
  result = ReaderB_Wakeup();//
  if (result == FM17622_SUCCESS){
      *polling_card |= BIT1;
  }
  fm17622_setcw(TX1_TX2_CW_DISABLE);
  if (*polling_card != 0)
    return FM17622_SUCCESS;
  else
    return FM17622_COMM_ERR;
}



#endif //end of "FM17622_DRIVER"
